package com.ghy.ic.mo.utils;

import com.csvreader.CsvWriter;
import org.apache.log4j.Logger;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * csv文件导出
 * @author ytree
 */
public class ExportUtil {

    private static final Logger LOGGER =Logger.getLogger(ExportUtil.class);

    private static final char CSV_COLUMN_SEPARATOR = ',';
    private static final String CSV_RN = "\r\n";
    private static final String CODE_FORMAT = "UTF-8";

    /**
     * csv通过浏览器下载并处理乱码
     * @param fileName 传入的文件名称
     * @param response http响应
     * @throws UnsupportedEncodingException 编解码异常
     */
    public static void responseSetProperties(String fileName, HttpServletResponse response) throws UnsupportedEncodingException {

        // 时间
        String date = JodaTimeUtil.date2String2(new Date());
        // 导出时的csv文件名
        String exportFileName = fileName + "_" + date + ".csv";
        // 设置浏览器保存响应发起下载(attachment; filename 必须为分号，
        // 若为逗号时会报ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION错误)
        response.setContentType("application/ms-txt.numberformat:@");
        response.setCharacterEncoding(CODE_FORMAT);
        response.setHeader("Pragma", "public");
        response.setHeader("Cache-Control", "max-age=30");
        response.setHeader("Content-Disposition",
                "attachment; filename=" + URLEncoder.encode(exportFileName, CODE_FORMAT));
    }

    /**
     * csv导出
     * @param dataList 数据集
     * @param colNames 列名称
     * @param mapKey 列名称对应的map key
     * @param os 输出流
     * @return boolean
     */
    public static boolean downloadCsvFile(List<Map<String, Object>> dataList, String colNames,
                                   String mapKey, OutputStream os){

        CsvWriter csvWriter = new CsvWriter(os, CSV_COLUMN_SEPARATOR, Charset.forName(CODE_FORMAT));
        return csvExportCode(csvWriter, colNames, mapKey, dataList);
    }

    /**
     * csv保存到本地
     * @param dataList 数据集
     * @param colNames 列名称
     * @param mapKey 列名称对应的map key
     * @param outPutPath 输出位置
     * @return boolean
     */
    public static boolean createCsvFile(List<Map<String, Object>> dataList, String colNames,
                                     String mapKey, String outPutPath){

        checkAndCreateFile(outPutPath);

        CsvWriter csvWriter = new CsvWriter(outPutPath, CSV_COLUMN_SEPARATOR, Charset.forName(CODE_FORMAT));
        return csvExportCode(csvWriter, colNames, mapKey, dataList);
    }

    /**
     * csv文件导出代码实现
     * @param csvWriter CsvWriter 对象
     * @param colNames 列名称
     * @param mapKey 列名称对应的map key
     * @param dataList 数据集
     * @return boolean
     */
    private static boolean csvExportCode(CsvWriter csvWriter, String colNames,
                                         String mapKey, List<Map<String, Object>> dataList){
        try {
            String[] colNameArr;
            String[] mapKeyArr;
            colNameArr = colNames.split(",");
            mapKeyArr = mapKey.split(",");
            // csv输出列头
            csvWriter.writeRecord(colNameArr);
            // csv输出数据值
            if (dataList != null){
                for (Map<String, Object> aDataList : dataList) {
                    String[] content = new String[colNameArr.length];
                    for (int j = 0; j < colNameArr.length; j++) {
                        content[j] = aDataList.get(mapKeyArr[j]).toString();
                    }
                    csvWriter.writeRecord(content, true);
                }
            }
            csvWriter.flush();

        } catch (IOException e) {
            LOGGER.error("csv导出出错 ： {}", e);
            return false;
        }finally {
            csvWriter.close();
        }
        return true;
    }

    /**
     * 文件校验
     * @param outPutPath csv文件输出位置
     */
    private static void checkAndCreateFile(String outPutPath){

        File file=new File(outPutPath);
        try{
            if(!file.exists()){
                file.createNewFile();
                LOGGER.info("文件不存在，新建成功！");
            }
            else{
                LOGGER.info("文件存在！");
            }
        }catch( Exception e){
            e.printStackTrace();
        }
    }

}
